package com.cryptoneedle.center.source.entity.metadata;


import com.bubbles.engine.data.core.entity.BaseEntity;
import com.cryptoneedle.center.source.key.metadata.SourceDatabaseKey;
import jakarta.persistence.*;
import lombok.*;
import lombok.experimental.Accessors;
import org.hibernate.annotations.Comment;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>description: 源数据源-数据库 </p>
 *
 * @author CryptoNeedle
 * @date 2025-06-19
 */
@Data
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true, exclude = {"sourceCatalog", "sourceTables"})
@ToString(callSuper = true, exclude = {"sourceCatalog", "sourceTables"})
@Entity
@EntityListeners(AuditingEntityListener.class)
@Table(schema = "public", name = "source_database")
@IdClass(SourceDatabaseKey.class)
@Comment("源数据源-数据库")
public class SourceDatabase extends BaseEntity {
    
    @Id
    @Comment("源数据源-目录名称")
    private String sourceCatalogName;
    
    @Comment("源数据源-系统编码")
    private String sourceSystemCode;
    
    @Id
    @Comment("源数据源-数据库名称")
    private String sourceDatabaseName;
    
    @Comment("源数据源-启用数据库")
    private Boolean sourceDatabaseEnabled;
    
    @Embedded
    private Statistic statistic;
    
    @Embedded
    private Transform transform;
    
    @Embedded
    private Doris doris;
    
    @Data
    @Accessors(chain = true)
    @NoArgsConstructor
    @AllArgsConstructor
    @Embeddable
    public static class Statistic {
        
        @Comment("统计信息-表数量")
        private Long statisticTableCount;
        
        @Comment("统计信息-视图数量")
        private Long statisticViewCount;
        
        @Comment("统计信息-列数量")
        private Long statisticColumnCount;
        
        @Comment("统计信息-约束数量")
        private Long statisticConstraintCount;
        
        @Comment("统计信息-索引数量")
        private Long statisticIndexCount;
        
        @Comment("统计信息-统计时间")
        private Date statisticDatetime;
    }
    
    @Data
    @Accessors(chain = true)
    @NoArgsConstructor
    @AllArgsConstructor
    @Embeddable
    public static class Transform {
        
        @Comment("转换-系统编码")
        private String transformSystemCode;
    }
    
    @Data
    @Accessors(chain = true)
    @NoArgsConstructor
    @AllArgsConstructor
    @Embeddable
    public static class Doris {
        
        @Comment("Doris分析时间")
        private Date dorisAnalyzeDatetime;
    }
    
    /**
     * 关联关系
     */
    
    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "sourceCatalogName", referencedColumnName = "sourceCatalogName", insertable = false, updatable = false)
    private SourceCatalog sourceCatalog;
    
    @OneToMany(mappedBy = "sourceDatabase", cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true)
    private List<SourceTable> sourceTables = new ArrayList<>();
    
    public SourceDatabase addSourceTable(SourceTable sourceTable) {
        this.sourceTables.add(sourceTable);
        sourceTable.setSourceDatabase(this);
        sourceTable.setSourceCatalogName(this.sourceCatalogName);
        sourceTable.setSourceDatabaseName(this.sourceDatabaseName);
        return this;
    }
    
    public SourceDatabase removeSourceTable(SourceTable sourceTable) {
        this.sourceTables.remove(sourceTable);
        sourceTable.setSourceDatabase(null);
        return this;
    }
    
    /**
     * 其他
     */
    
    public SourceDatabaseKey getKey() {
        return new SourceDatabaseKey().setSourceCatalogName(this.sourceCatalogName)
                                      .setSourceDatabaseName(this.sourceDatabaseName);
    }
    
    public String getStringKey() {
        return getKey().toString();
    }
}